<?php
declare(strict_types=1);

namespace app\utils;


use think\facade\Log;

class SignUtil
{
    const key = 'No0NqsXSJsPVrgFu';

    /**
     * 校验SIGN
     * @param array $arr
     * @return bool
     */
    public static function verify(array $arr): bool
    {
        if (isset($arr['s'])) {
            unset($arr['s']);
        }

        $_sign = $arr['_sign'];
        unset($arr['_sign']);

        $_timestamp = $arr['_timestamp'];
        unset($arr['_timestamp']);

        ksort($arr);

        $urlValues = [];
        foreach ($arr as $key => $value) {
            if ($value == '') {
                continue;
            }
            $urlValues[] = "{$key}={$value}";
        }
        $urlValues[] = "_timestamp={$_timestamp}_M8yLiMFOdBj0E0F7";

        $urlValue = implode('&', $urlValues);
        // 对url进行url转义
        $strEncode = rawurlencode($urlValue);
        $sign = strtoupper(md5(base64_encode($strEncode)));
        if ($_sign == $sign) {
            return true;
        }
        Log::alert('sign解析错误', [
            '排序后的字符串' => $urlValue,
            '转义后的字符串' => $strEncode,
            'BASE64字符串' => base64_encode($strEncode),
            'md5后的字符串' => $sign
        ]);
        return false;
    }

    /**
     * 对数组进行加密
     * @param array $data
     * @param int $timestamp
     * @return string
     */
    public static function encryptArray(array $data, int $timestamp)
    {
        ksort($data);

        $urlValues = [];
        foreach ($data as $key => $value) {
            if (empty($value)) {
                continue;
            }
            $urlValues[] = "{$key}={$value}";
        }
        $urlValues[] = "_timestamp={$timestamp}";

        $urlValue = implode('&', $urlValues);
        // 对url进行url转义
        $strEncode = rawurlencode($urlValue);

        // 使用base64进行处理原字符串
        return strtoupper(md5(base64_encode($strEncode)));
    }

    /**
     * 解码加密字符串
     * @param string $body
     * @return false|string
     */
    public static function decrypt(string $body)
    {
        return openssl_decrypt(base64_decode($body), 'AES-128-CBC', self::key, 1, self::key);
    }
}